package com.javase.homework.module2;

import java.util.Scanner;

/*
2. 编程实现控制台版并支持两人对战的五子棋游戏。

  （1）绘制棋盘 - 写一个成员方法实现

  （2）提示黑方和白方分别下棋并重新绘制棋盘 - 写一个成员方法实现。

  （3）每当一方下棋后判断是否获胜 - 写一个成员方法实现。

  特别说明：此五子棋游戏是按照棋盘二维数组所对应的行列的具体元素进行输入的，并不是按照数组下标进行输入！
 */
public class GoBang {

    //建立成员变量，定义二维数组来描述棋盘
    private static char[][] chessBoard = new char[17][17];

    //建立成员变量，标明一个标识，对游戏进行不断循环，只有当flag为false时，游戏才能结束
    boolean flag = true;

    //方法1.绘制棋盘
    public static void showChess() {

        //临时数组存放列与行号码
        char[] row = {' ','0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

        //遍历棋盘插入数据
        for (int i = 0 ; i < chessBoard.length ; i++) {

            for (int j = 0 ; j < chessBoard[i].length ; j++) {

                //当二维数组到达第一列时，将临时数列的数据插入第一列
                if (j == 0) {

                    chessBoard[i][j] = row[i];

                    //当二维数组到达第一行时，将临时数列的数据插入第一行
                } else if(i == 0)  {

                    chessBoard[i][j] = row[j];

                    //其余情况插入+字符
                } else {

                    chessBoard[i][j] = '+';

                }

            }

        }

        //打印棋盘
        for (int i = 0 ; i < chessBoard.length ; i++) {

            for (int j = 0 ; j < chessBoard[i].length ; j++) {

                System.out.print(chessBoard[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("按照棋盘所对应的行列的具体字符进行输入");
    }

    Scanner sc = new Scanner(System.in);

    //方法2、开始下棋，黑方和白方分别下棋并重新绘制棋盘
    public void playChess() {

        //临时数组存放列与行号码
        char[] chessRow = {' ','0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

        //设置player变量进行黑白方转换
        String player = "黑方";

        //游戏体，在flag变为false之前，一直进行下棋游戏
        outer:while (flag == true) {

            //控制台提示哪一方开始下棋
            if (player.equals("黑方")) {

                System.out.println("请黑方落子");

            } else if (player.equals("白方")) {

                System.out.println("请白方落子");

            }

            // 特别说明：此五子棋游戏是按照棋盘二维数组所对应的行列的具体元素进行输入的，并不是按照数组下标进行输入！！！
            //开始输入落子的行数
            System.out.println("请输入落子在第几行");
            String stringRow = sc.next();

            //建立变量用于记录棋盘二维数组的行下标
            int x = -1;

            //对输入的内容进行判断，若字符串长度大于1，则说明输入的内容不符合规范，需要重新输入
            if (stringRow.length() > 1) {

                System.out.println("落子的行数不在棋盘范围内，请重新输入");
                continue;

            //输入的字符串长度等于1，则将字符串转化为char类型
            } else if (stringRow.length() == 1) {

                char row = stringRow.charAt(0);

                //将输入的字符串转为char类型后，遍历行列临时数组，与数组元素进行匹配
                for (int i = 0; i < chessRow.length; i++) {

                    //相等说明在棋盘内，将下标值赋值给x
                    if (row == chessRow[i]) {
                        x = i;
                        break;
                    }
                }
            }

            //若x仍为初始值，则说明输入的内容与数组元素不符，不在棋盘范围内，跳出本次循环
            if (x == -1) {

                System.out.println("落子的行数不在棋盘范围内，请重新输入");
                continue;

            }


            //开始输入落子的列数
            System.out.println("请输入落子在第几列");
            String stringColumn = sc.next();

            //建立变量用于记录棋盘二维数组的列下标
            int y = -1;

            //以下代码与行相关的代码逻辑一致
            if (stringColumn.length() > 1) {

                System.out.println("落子的列数不在棋盘范围内，请重新输入");
                continue;

            } else if (stringColumn.length() == 1) {

                char column = stringColumn.charAt(0);

                for (int i = 0; i < chessRow.length; i++) {
                    if (chessRow[i] == column) {
                        y = i;
                        break;
                    }
                }
            }

            if (y == -1) {

                System.out.println("落子的列数不在棋盘范围内，请重新输入");
                continue;

            }

            //将落子的行列下标传入棋盘二维数组，如果该元素为@或O，则说明该位置已有棋子，跳出本次循环
            if (chessBoard[x][y] == '@' || chessBoard[x][y] == 'O') {

                System.out.println("该位置已有棋子，请重新落子");
                continue;

                //该元素为+，则说明该位置没有棋子，进行落子
            } else if (chessBoard[x][y] == '+') {

                //黑方落子后，将player赋值为白方
                if (player.equals("黑方")) {

                    chessBoard[x][y] = '@';
                    player = "白方";

                //同样，白方落子后，将player赋值为黑方，循环进行落子
                } else if (player.equals("白方")) {

                    chessBoard[x][y] = 'O';
                    player = "黑方";

                }
            }



            //每次落子后，对棋盘进行打印
            for (int i = 0; i < chessBoard.length; i++) {

                for (int j = 0; j < chessBoard[i].length; j++) {

                    System.out.print(chessBoard[i][j] + " ");
                }
                System.out.println();
            }

            this.judgeWin();
        }

    }

    //方法3、判断胜负
    public void judgeWin() {

        //设置两个变量对相邻棋子数量进行记录
        int blackCount = 0;
        int whiteCount = 0;


        //从左上到右下
        for (int i = 0; i < chessBoard.length - 1; i++) {

            //左上到右下，即二维数组的两个下标相同
            if (chessBoard[i][i] == '@') {

                //每有一颗棋子相邻就对count加一
                blackCount++;

                //当count等于5时，则说明五子胜利
                if (blackCount == 5) {

                    System.out.println("黑方胜利！游戏结束");
                    flag = false;

                }

            //判断下一颗棋子时候为相同棋子，若不是同一棋子则将count置零
            } else if (chessBoard[i+1][i+1] != '@') {

                blackCount = 0;

            } else if (chessBoard[i][i] == 'O') {

                whiteCount++;

                if (whiteCount == 5) {

                    System.out.println("白方胜利！游戏结束");
                    flag = false;

                }

            }else if (chessBoard[i+1][i+1] != 'O') {

                whiteCount = 0;

            }

        }

        //右上到左下
        for (int i = 0;i < chessBoard.length - 1; i++) {

            //[i][chessBoard.length-1]获取的是当前行的对于对角线上的最右侧的元素
            if (chessBoard[i][chessBoard.length-1] == '@') {

                blackCount++;

                if (blackCount == 5) {

                    System.out.println("黑方胜利！游戏结束");
                    flag = false;

                }

            //判断下一个元素是否为相同棋子
            } else if (chessBoard[i+1][chessBoard.length-1-i] != '@') {

                blackCount = 0;

            } else if (chessBoard[i][chessBoard.length-1] == 'O') {

                whiteCount++;

                if (whiteCount == 5) {

                    System.out.println("白方胜利！游戏结束");
                    flag = false;

                }

            }else if (chessBoard[i+1][chessBoard.length-1-i] != 'O') {

                whiteCount = 0;

            }
        }


        //横排
        for (int i = 0; i < chessBoard.length - 1; i++) {

            for (int j = 0; j < chessBoard[i].length - 1; j++) {
                //对二维数组进行遍历
                if (chessBoard[i][j] == '@') {

                    blackCount++;

                    if (blackCount == 5) {

                        System.out.println("黑方胜利！游戏结束");
                        flag = false;

                    }
                //判断横排下一个元素是否为相同元素
                } else if (chessBoard[i][j+1] != '@') {

                    blackCount = 0;

                } else if (chessBoard[i][j] == 'O') {

                    whiteCount++;

                    if (whiteCount == 5) {

                        System.out.println("白方胜利！游戏结束");
                        flag = false;

                    }

                }else if (chessBoard[i][j+1] != 'O') {

                    whiteCount = 0;

                }

            }

        }



        //竖排
        for (int i = 0; i < chessBoard.length - 1; i++) {

            for (int j = 0; j < chessBoard[i].length - 1; j++) {
                //对二维数组进行遍历
                if (chessBoard[i][j] == '@') {

                    blackCount++;

                    if (blackCount == 5) {

                        System.out.println("黑方胜利！游戏结束");
                        flag = false;

                    }
                    //对竖排的下一个元素进行判断，如果不是同一个棋子，则把计数归零
                } else if (chessBoard[i+1][j] != '@') {

                    blackCount = 0;

                } else if (chessBoard[i][j] == 'O') {

                    whiteCount++;

                    if (whiteCount == 5) {

                        System.out.println("白方胜利！游戏结束");
                        flag = false;

                    }

                }else if (chessBoard[i+1][j] != 'O') {

                    whiteCount = 0;

                }

            }

        }
    }

}
